home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / et / et3_0-a1.lha / et3 / src / ColorPicker.C < prev    next >
C/C++ Source or Header  |  1992-08-26  |  18KB  |  729 lines

  1. #ifdef __GNUG__
  2. #pragma implementation
  3. #endif
  4.  
  5. #include "ColorPicker.h"
  6.  
  7. #include "ET++.h"
  8. #include "ScrollBar.h"
  9. #include "Slider.h"
  10. #include "WindowPort.h"
  11. #include "Window.h"
  12. #include "Buttons.h"
  13. #include "Filler.h"
  14. #include "Look.h"
  15. #include "BorderItems.h"
  16. #include "Fields.h"
  17. #include "Math.h"
  18. #include "PopupItem.h"
  19. #include "OrdColl.h"
  20. #include "CollView.h"
  21.  
  22. const int cIdValSlider  =   cIdFirstUser + 1,
  23.       cIdRGBSlider  =   cIdFirstUser + 2,
  24.       cIdPicker     =   cIdFirstUser + 5,
  25.       cIdWheel      =   cIdFirstUser + 7,
  26.       cIdReset      =   cIdFirstUser + 8,
  27.       cIdHueNum     =   cIdFirstUser + 9,
  28.       cIdSatNum     =   cIdFirstUser + 10,
  29.       cIdSlider     =   cIdFirstUser + 11,
  30.       cIdNumItem    =   cIdFirstUser + 12,
  31.       cIdPopup      =   cIdFirstUser + 13,
  32.       cIdSetColor   =   cIdFirstUser + 14;
  33.       
  34. static ColorPicker *gPicker;
  35.  
  36. ONEXIT(ColorPicker)
  37. {
  38.     SafeDelete(gPicker);
  39. }
  40.  
  41. //---- ColorCell ---------------------------------------------------------------
  42.  
  43. class ColorCell: public VObject {
  44.     RGBColor *rc;
  45. public:
  46.     MetaDef(ColorCell);
  47.     ColorCell(RGB c, Point e, bool hfix= TRUE);
  48.     ColorCell(RGBColor *c, Point e, bool hfix= TRUE);
  49.     ~ColorCell();
  50.     void DrawAll(Rectangle r, bool highlight);
  51.     void SetColor(RGB c)
  52.     { if (rc->SetRGB(&c, MaxWord)) ForceRedraw(); }
  53.     RGB GetColor()
  54.     { return RGB(rc->GetRed(), rc->GetGreen(), rc->GetBlue()); }
  55.     Command *DoLeftButtonDownCommand(Point, Token t, int);
  56. };
  57.  
  58. ColorCell::~ColorCell()
  59. {
  60.     SafeDelete(rc);
  61. }
  62.  
  63. ColorCell::ColorCell(RGB c, Point e, bool hfix) : VObject(e)
  64. {
  65.     rc= new RGBColor(c);
  66.     rc->SetPrec(MaxWord);
  67.     SetFlag(eVObjVFixed);
  68.     SetFlag(eVObjHFixed, hfix);
  69. }
  70.  
  71. ColorCell::ColorCell(RGBColor *c, Point e, bool hfix) : VObject(e)
  72. {
  73.     rc= c;
  74.     rc->SetPrec(MaxWord);
  75.     SetFlag(eVObjVFixed);
  76.     SetFlag(eVObjHFixed, hfix);
  77. }
  78.  
  79. //---- DragColor ---------------------------------------------------------------
  80.  
  81. class DragColor: public Command {
  82.     ColorCell *from;
  83. public:
  84.     DragColor(ColorCell *f);
  85.     void TrackFeedback(Point, Point, bool);
  86.     Command *TrackMouse(TrackPhase atp, Point ap, Point, Point np);
  87. };
  88.  
  89. DragColor::DragColor(ColorCell *f) : Command(123, "Drag Color")
  90. {
  91.     from= f;
  92. }
  93.  
  94. void DragColor::TrackFeedback(Point, Point np, bool)
  95. {
  96.     GrLine(from->contentRect.Center(), np);
  97. }
  98.  
  99. static VObject *drag;
  100. static bool dodrag;
  101.  
  102. Command *DragColor::TrackMouse(TrackPhase atp, Point, Point, Point np)
  103. {
  104.     VObject *v= 0;
  105.     Token t((EventCodes)(eEvtPseudo + 300), eFlgNone, np);
  106.     
  107.     Window *w= from->GetWindow();
  108.     if (w) {
  109.     drag= 0;
  110.     dodrag= TRUE;
  111.     w->DispatchEvents(t.Pos, t, w);
  112.     dodrag= FALSE;
  113.     v= drag;
  114.     }
  115.     if (atp == eTrackRelease) {
  116.     if (v) {
  117.         if (v == from) {
  118.         RGB c= from->GetColor();
  119.         from->Control(cIdSetColor, 1, &c);
  120.         } else {
  121.         fprintf(stderr, "%s\n", v->ClassName());
  122.         if (v->IsKindOf(CompositeVObject)) {
  123.             ColorCell *cc= new ColorCell(from->GetColor(), Point(20));
  124.             v->Add(cc);
  125.             v->ExtentChanged(cc);
  126.             v->ForceRedraw();
  127.         }
  128.         }
  129.     }
  130.     return gNoChanges;
  131.     }
  132.     return this;
  133. }
  134.  
  135. //---- CPicker -----------------------------------------------------------------
  136.  
  137. class CPicker: public Box {
  138. public:
  139.     MetaDef(CPicker);
  140.     CPicker() : Box(cIdPicker, gPoint1, gPoint0,
  141.                     (VObjAlign)(eVObjHExpand+eVObjVExpand))
  142.     { }
  143.     virtual void SetColor(RGB, bool)
  144.     { }
  145.     virtual RGB GetColor()
  146.     { return RGB(0,0,0); }
  147.     virtual VObject *DoMakeContent()
  148.     { return 0; }
  149.     void SetContainer(VObject *v);
  150. };
  151.  
  152. NewMetaImpl0(CPicker,Box);
  153.  
  154. void CPicker::SetContainer(VObject *v)
  155. {
  156.     if (Size() <= 0)
  157.     Add(new BorderItem(AsString(), DoMakeContent()));
  158.     Box::SetContainer(v);
  159. }
  160.  
  161. //---- ColorSlider -------------------------------------------------------------
  162.  
  163. class ColorSlider : public VBox {
  164.     IntField *num;
  165.     Slider *slider;
  166. public:
  167.     ColorSlider(int id, char *label);
  168.     void SetVal(int val, bool redraw);
  169.     void Control(int id, int part, void *val);
  170.     int GetVal()
  171.     { return slider->GetMax().y-slider->GetVal().y; }
  172. };
  173.  
  174. ColorSlider::ColorSlider(int id, char *label)
  175.             : VBox(gPoint5, (VObjAlign)(eVObjHCenter+eVObjVExpand))
  176. {
  177.     SetId(id);
  178.     slider= new Slider(cIdSlider, eVert, TRUE);
  179.     slider->SetMax(255, FALSE);
  180.     Add(slider);
  181.     num= new IntField(cIdNumItem, 0, 0, 255);
  182.     Add(new HBox(5, eVObjVBase, new TextItem(label), num, 0));
  183. }
  184.  
  185. void ColorSlider::SetVal(int val, bool redraw)
  186. {
  187.     slider->SetVal(slider->GetMax().y-val, redraw);
  188.     num->SetValue(val, redraw);
  189. }
  190.  
  191. void ColorSlider::Control(int id, int part, void *val)
  192. {
  193.     switch (id) {
  194.     case cIdSlider:
  195.     if (part == eSliderThumb) {
  196.         num->SetValue(slider->GetMax().y-slider->GetVal().y, TRUE);
  197.         Control(GetId(), eSliderThumb, 0);
  198.     }
  199.     break;
  200.     case cIdNumItem:
  201.     if (part == cPartValueChanged) {
  202.         slider->SetVal(slider->GetMax().y-num->GetValue(), TRUE);
  203.         Control(GetId(), eSliderThumb, 0);
  204.     }
  205.     break;
  206.     default:
  207.     VBox::Control(id, part, val);
  208.     break;
  209.     }
  210. }
  211.  
  212. //---- ColorCell ---------------------------------------------------------------
  213.  
  214. NewMetaImpl(ColorCell,VObject, (TP(rc)));
  215.  
  216. void ColorCell::DrawAll(Rectangle r, bool highlight)
  217. {
  218.     if (IsOpen() && r.Clip(contentRect)) {
  219.     if (highlight || TestFlag(eVObjHighlight)) {
  220.         GrPaintRect(r, gHighlightColor);
  221.         GrPaintRect(contentRect.Inset(2), rc);
  222.     } else
  223.         GrPaintRect(contentRect, rc);
  224.     }
  225. }
  226.  
  227. Command *ColorCell::DoLeftButtonDownCommand(Point, Token, int)
  228. {
  229.     return new DragColor(this);
  230. }   
  231.  
  232. //---- ColorWheel --------------------------------------------------------------
  233.  
  234. static short StdSectors[] = { 36, 36, 18, 18, 1, 0 };
  235.  
  236. class ColorWheel: public VObject {
  237. protected:
  238.     short *sectors;
  239.     int circles, maxix, sz;
  240.     HSVColor hsv;
  241.     RGBColor *palette;
  242.     Point border;
  243.     ImageCache cache;
  244. public:
  245.     MetaDef(ColorWheel);
  246.     ColorWheel(int id, short *sectors= StdSectors);
  247.     ~ColorWheel();
  248.     void Draw(Rectangle cr);
  249.     Command *DoLeftButtonDownCommand(Point, Token, int);
  250.     void SetColor(HSVColor c, bool redraw);
  251.     void SetColor2(HSVColor c, bool redraw);
  252.     Rectangle DotRect();
  253.     HSVColor MapPointToColor(Point p);
  254.     Metric GetMinSize()
  255.     { return Metric(245); }
  256.     HSVColor GetColor()
  257.     { return hsv; }
  258. };
  259.  
  260. //---- PickerCommand -----------------------------------------------------------
  261.  
  262. class PickerCommand: public Command {
  263.     ColorWheel *wheel;
  264. public:
  265.     PickerCommand(class ColorWheel *w) : Command("pick")
  266.     { wheel= w; }
  267.     Command *TrackMouse(TrackPhase, Point ap, Point, Point np);
  268.     void TrackFeedback(Point, Point, bool)
  269.     { }
  270. };
  271.  
  272. Command *PickerCommand::TrackMouse(TrackPhase atp, Point, Point, Point np)
  273. {
  274.     wheel->SetColor2(wheel->MapPointToColor(np), TRUE);
  275.     if (atp == eTrackRelease)
  276.     return gNoChanges;
  277.     return this;
  278. }
  279.  
  280. //---- ColorWheel --------------------------------------------------------------
  281.  
  282. NewMetaImpl(ColorWheel,VObject, (TV(sectors,circles), T(circles), T(maxix), T(border)));
  283.  
  284. ColorWheel::ColorWheel(int id, short *sects) : VObject(id)
  285. {
  286.     sectors= sects;
  287.     for (sz= circles= 0; sectors[circles]; circles++)
  288.     sz+= sectors[circles];
  289.     border= 6;
  290.     palette= new RGBColor[sz];
  291.     maxix= 0;
  292.     SetColor(HSVColor(0, MaxWord, MaxWord), FALSE);
  293.     SetFlag(eVObjHFixed|eVObjVFixed);
  294. }
  295.  
  296. ColorWheel::~ColorWheel()
  297. {
  298.     SafeDelete(palette);
  299. }
  300.  
  301. HSVColor ColorWheel::MapPointToColor(Point p)
  302. {
  303.     HSVColor hc= hsv;
  304.     double rad= contentRect.Inset(border).extent.x / 2.0;
  305.  
  306.     hc.hue= contentRect.PointToAngle(p);
  307.     hc.saturation= (int) (Length(p - contentRect.Center()) / rad
  308.                             * (double)MaxWord + 0.5);
  309.     return hc;
  310. }
  311.  
  312. Rectangle ColorWheel::DotRect()
  313. {
  314.     Rectangle mark(13), inner= contentRect.Inset(border);
  315.     double w= (double) inner.extent.x / (double) MaxWord * hsv.saturation / 2.0,
  316.        h= (double) inner.extent.y / (double) MaxWord * hsv.saturation / 2.0;
  317.     mark.origin= contentRect.Center() 
  318.             + PolarToPoint((double)(hsv.hue), w, h) - mark.extent/2;
  319.     return mark;
  320. }
  321.  
  322. void ColorWheel::SetColor(HSVColor c, bool redraw)
  323. {
  324.     if (hsv.hue != c.hue || hsv.saturation != c.saturation) {
  325.     if (redraw)
  326.         InvalidateRect(DotRect());
  327.     hsv.hue= c.hue;
  328.     hsv.saturation= Math::Min(c.saturation, (short) MaxWord);
  329.     if (redraw)
  330.         InvalidateRect(DotRect());
  331.     }
  332.     if (c.value != hsv.value) {
  333.     int i, cir;        
  334.     bool invalidate= FALSE;
  335.  
  336.     hsv.value= c.value;
  337.  
  338.     for (i= cir= 0; cir < circles; cir++) {
  339.         int sat= (MaxWord * (circles-1-cir)) / circles;
  340.         for (int h= 0; h < sectors[cir]; h++) {
  341.         int hue= (360 * h + (360/sectors[cir]/2)) / sectors[cir];
  342.         if (palette[i].SetHSV(hue, sat, hsv.value, MaxWord))
  343.             invalidate= TRUE;
  344.         i++;
  345.         }
  346.     }
  347.  
  348.     if (invalidate) {
  349.         ForceRedraw();
  350.         cache.Invalidate();
  351.     }
  352.     }
  353. }
  354.  
  355. void ColorWheel::SetColor2(HSVColor c, bool redraw)
  356. {
  357.     if (hsv.hue != c.hue || hsv.saturation != c.saturation) {
  358.     SetColor(c, redraw);
  359.     Control(GetId(), cPartValueChanged, (void*) &hsv);
  360.     }
  361. }
  362.  
  363. void ColorWheel::Draw(Rectangle cr)
  364. {
  365.     if (cache.Open(cr)) {
  366.     Rectangle r(contentRect.Inset(border));
  367.     Point Step= r.extent/(2*circles-1);
  368.     int sat, i;
  369.  
  370.     for (i= sat= 0; sat < circles; sat++) {
  371.         for (int hue= 0; hue < sectors[sat]; hue++)
  372.         GrPaintWedge(r, 360 * hue / sectors[sat], 360/sectors[sat],
  373.                                 &palette[i++]);
  374.         r= r.Inset(Step);
  375.     }
  376.     GrSetPenNormal();
  377.     GrSetPenSize(2);
  378.     GrStrokeOval(contentRect.Inset(border));
  379.     cache.Close();
  380.     }
  381.     
  382.     GrSetPenSize(3);
  383.     GrSetPenInk(gInkWhite);
  384.     GrStrokeOval(DotRect());
  385.     GrSetPenNormal();
  386.     GrSetPenInk(gInkBlack);
  387.     GrStrokeOval(DotRect().Inset(1));
  388. }
  389.  
  390. Command *ColorWheel::DoLeftButtonDownCommand(Point, Token, int)
  391. {
  392.     return new PickerCommand(this);
  393. }
  394.  
  395. //---- HSVPicker ---------------------------------------------------------------
  396.  
  397. class HSVPicker: public CPicker {
  398.     ColorSlider *valslider;
  399.     ColorWheel *wheel;
  400.     IntField *hNum, *sNum;
  401. public:
  402.     MetaDef(HSVPicker);
  403.     HSVPicker() : CPicker()
  404.     { }
  405.     void SetColor(RGB, bool);
  406.     void Control(int id, int part, void *val);
  407.     RGB GetColor();
  408.     char *AsString()
  409.     { return "HSV"; }
  410.     VObject *DoMakeContent();
  411. };
  412.  
  413. NewMetaImpl(HSVPicker,CPicker, (TP(valslider), TP(wheel), TP(hNum), TP(sNum)));
  414.  
  415. VObject *HSVPicker::DoMakeContent()
  416. {
  417.     wheel= new ColorWheel(cIdWheel);
  418.     valslider= new ColorSlider(cIdValSlider, "V:");
  419.     hNum= new IntField(cIdHueNum, 0, 0, 359);
  420.     sNum= new IntField(cIdSatNum, 0, 0, 255);
  421.  
  422.     return new Expander(cIdPicker, eHor, Point(20),
  423.     new VBox(5, eVObjVGapExpand,
  424.         wheel,
  425.         new HBox(10, (VObjAlign)(eVObjVBase+eVObjHGapExpand), 
  426.         new HBox(5, eVObjVBase, new TextItem("Hue:"), hNum, 0),
  427.         new HBox(5, eVObjVBase, new TextItem("Saturation:"), sNum, 0),
  428.         0
  429.         ),
  430.         0
  431.     ),
  432.     valslider,
  433.     0
  434.     );
  435. }
  436.  
  437. RGB HSVPicker::GetColor()
  438. {
  439.     return HSVColor(hNum->GetValue(), sNum->GetValue(), valslider->GetVal());
  440. }
  441.  
  442. void HSVPicker::SetColor(RGB c, bool redraw)
  443. {
  444.     HSVColor hsv(c);
  445.     wheel->SetColor(hsv, redraw);
  446.     hNum->SetValue(hsv.hue, redraw);
  447.     sNum->SetValue(hsv.saturation, redraw);
  448.     valslider->SetVal(hsv.value, redraw);
  449. }
  450.  
  451. void HSVPicker::Control(int id, int part, void *val)
  452. {
  453.     switch (id) {
  454.     case cIdHueNum:
  455.     if (part == cPartValueChanged) {
  456.         HSVColor color(hNum->GetValue(), sNum->GetValue(), valslider->GetVal());
  457.         wheel->SetColor(color, TRUE);
  458.         Control(cIdPicker, cPartValueChanged, 0);
  459.     }
  460.     break;
  461.     case cIdSatNum:
  462.     if (part == cPartValueChanged) {
  463.         HSVColor color(hNum->GetValue(), sNum->GetValue(), valslider->GetVal());
  464.         wheel->SetColor(color, TRUE);
  465.         Control(cIdPicker, cPartValueChanged, 0);
  466.     }
  467.     break;
  468.     case cIdValSlider:
  469.     if (part == eSliderThumb) {
  470.         HSVColor color(hNum->GetValue(), sNum->GetValue(), valslider->GetVal());
  471.         wheel->SetColor(color, TRUE);
  472.         Control(cIdPicker, cPartValueChanged, 0);
  473.     }
  474.     break;
  475.     case cIdWheel:
  476.     if (part == cPartValueChanged) {
  477.         HSVColor color(wheel->GetColor());
  478.         hNum->SetValue(color.hue, TRUE);
  479.         sNum->SetValue(color.saturation, TRUE);
  480.         Control(cIdPicker, cPartValueChanged, 0);
  481.     }
  482.     break;
  483.     default:
  484.     CPicker::Control(id, part, val);
  485.     break;
  486.     }
  487. }
  488.  
  489. //---- RGBPicker ---------------------------------------------------------------
  490.  
  491. class RGBPicker: public CPicker {
  492.     ColorSlider *red, *green, *blue;
  493. public:
  494.     MetaDef(RGBPicker);
  495.     RGBPicker() : CPicker()
  496.     { }
  497.     void SetColor(RGB, bool redraw);
  498.     void Control(int id, int part, void *val);
  499.     RGB GetColor()
  500.     { return RGB(red->GetVal(), green->GetVal(), blue->GetVal()); }
  501.     char *AsString()
  502.     { return "RGB"; }
  503.     VObject *DoMakeContent();
  504. };
  505.  
  506. NewMetaImpl(RGBPicker,CPicker, (TP(red), TP(green), TP(blue)));
  507.  
  508. VObject *RGBPicker::DoMakeContent()
  509. {
  510.     return new Expander(cIdPicker, eHor, Point(20),
  511.     red= new ColorSlider(cIdRGBSlider, "R:"),
  512.     green= new ColorSlider(cIdRGBSlider, "G:"),
  513.     blue= new ColorSlider(cIdRGBSlider, "B:"),
  514.     0
  515.     );
  516. }
  517.  
  518. void RGBPicker::Control(int id, int part, void *val)
  519. {
  520.     if (id == cIdRGBSlider && part == eSliderThumb)
  521.     CPicker::Control(cIdPicker, cPartValueChanged, 0);
  522.     else
  523.     CPicker::Control(id, part, val);
  524. }
  525.  
  526. void RGBPicker::SetColor(RGB color, bool redraw)
  527. {
  528.     red->SetVal(color.red, redraw);
  529.     green->SetVal(color.green, redraw);
  530.     blue->SetVal(color.blue, redraw);
  531. }
  532.  
  533. //---- PalettePicker -----------------------------------------------------------
  534.  
  535. class PalettePicker: public CPicker {
  536.     CollectionView *cv;
  537.     RGB c;
  538. public:
  539.     MetaDef(PalettePicker);
  540.     PalettePicker() : CPicker()
  541.     { }
  542.     RGB GetColor();
  543.     void SetColor(RGB cc, bool)
  544.     { c= cc; }
  545.     VObject *DoMakeContent();
  546.     char *AsString()
  547.     { return "Palette"; }
  548.     void Control(int id, int part, void *val);
  549. };
  550.  
  551. NewMetaImpl0(PalettePicker,CPicker);
  552.  
  553. VObject *PalettePicker::DoMakeContent()
  554. {
  555.     OrdCollection *col= new OrdCollection;
  556.     for (int i= 0; i < 256; i++)
  557.     col->Add(new ColorCell(new RGBColorCell(i), Point(15)));
  558.     cv= new CollectionView(this, col, eCVDefault, 16, 16);
  559.     cv->SetId(cIdPicker);
  560.     cv->SetGap(gPoint1);
  561.     return cv;
  562. }
  563.  
  564. RGB PalettePicker::GetColor()
  565. {
  566.     Rectangle s(cv->GetSelection());
  567.     ColorCell *cc= (ColorCell*) cv->GetItem(s.origin.x, s.origin.y);
  568.     if (cc)
  569.     return cc->GetColor();
  570.     return c;
  571. }
  572.  
  573. void PalettePicker::Control(int id, int part, void *val)
  574. {
  575.     if (part == cPartCollSelect)
  576.     CPicker::Control(cIdPicker, cPartValueChanged, 0);
  577.     else
  578.     CPicker::Control(id, part, val);
  579. }
  580.  
  581. //---- MyColors ----------------------------------------------------------------
  582.  
  583. class MyColors: public HBox {
  584. public:
  585.     MyColors() : HBox(gPoint4, eVObjHLeft)
  586.     { }
  587.     Command *DoOtherEventCommand(Point p, Token t);
  588. };
  589.  
  590. Command *MyColors::DoOtherEventCommand(Point p, Token t)
  591. {
  592.     if (dodrag) {
  593.     drag= this;
  594.     } else
  595.     HBox::DoOtherEventCommand(p, t);
  596.     return gNoChanges;
  597. }
  598.  
  599. //---- ColorPicker -------------------------------------------------------------
  600.  
  601. NewMetaImpl(ColorPicker,Dialog, (TP(oldcell), TP(newcell)));
  602.         
  603. ColorPicker::ColorPicker(char *name) : Dialog(name)
  604. {
  605.     current= 0;
  606.     pickers= new OrdCollection;
  607.     pickers->Add(new PalettePicker);
  608.     pickers->Add(new HSVPicker);
  609.     pickers->Add(new RGBPicker);
  610. }
  611.  
  612. void ColorPicker::DoSetup()
  613. {
  614.     //newcell->SetColor(color);
  615.     //oldcell->SetColor(oldcolor);
  616. }
  617.  
  618. void ColorPicker::DoSetDefaults()
  619. {
  620.     //newcell->SetColor(color);
  621.     //oldcell->SetColor(oldcolor);
  622. }
  623.  
  624. VObject *ColorPicker::DoMakeContent()
  625. {
  626.     Iter next(pickers);
  627.     CPicker *p;
  628.  
  629.     Menu *m= new Menu("Model", FALSE);
  630.     for (int id= 0; p= (CPicker*) next(); id++)
  631.     m->AppendItem(p->AsString(), id);
  632.  
  633.     RGB rc(color);
  634.     
  635.     bag= new MyColors;
  636.     bag->Add(new ColorCell(RGB(200,0,0), Point(20)));
  637.     bag->Add(new ColorCell(RGB(0,200,0), Point(20)));
  638.     bag->Add(new ColorCell(RGB(0,0,200), Point(20)));
  639.     
  640.     return
  641.     new Matte(
  642.         new HExpander(gPoint10,
  643.         border= new VExpander(gPoint10,
  644.             (CPicker*)pickers->At(current),
  645.             //new Scroller(bag= new HBox(gPoint4, eVObjHLeft)),
  646.             new BorderItem("My Colors", new Clipper(bag)),
  647.             0
  648.         ),
  649.         new VExpander(gPoint10,
  650.             new BorderItem("Old/New",
  651.             new VBox(gPoint0, (VObjAlign)(eVObjHExpand),
  652.                 oldcell= new ColorCell(rc, Point(75, 45), FALSE),
  653.                 newcell= new ColorCell(rc, Point(75, 45), FALSE),
  654.                 0
  655.             )
  656.             ),
  657.             new Filler(gPoint10),
  658.             new PopupButton(cIdPopup, current, m),
  659.             new Filler(gPoint10),
  660.             new ActionButton(cIdReset,  "Reset"),
  661.             new ActionButton(cIdCancel, "Cancel"),
  662.             new ActionButton(cIdYes,    "Set Color", TRUE),
  663.             0
  664.         ),
  665.         0
  666.         )
  667.     );
  668. }
  669.  
  670. void ColorPicker::Control(int id, int part, void *val)
  671. {
  672.     CPicker *picker;
  673.     
  674.     switch (id) {
  675.     case cIdPopup:
  676.     if (part == cPartToggle && current != (int)val) {
  677.         SetFirstHandler(0);
  678.         current= (int)val;
  679.         picker= (CPicker*) pickers->At(current);
  680.         if (picker) {
  681.         border->SetAt(0, picker);
  682.         picker->SetColor(color, FALSE);
  683.         }
  684.     }
  685.     break;
  686.     
  687.     case cIdPicker:
  688.     if (part == cPartValueChanged) {
  689.         picker= (CPicker*) pickers->At(current);
  690.         color= picker->GetColor();
  691.         newcell->SetColor(color);
  692.     }
  693.     break;
  694.     
  695.     case cIdSetColor:
  696.     newcell->SetColor(*((RGB*)val));
  697.     break;
  698.  
  699.     case cIdReset:
  700.     color= oldcolor;
  701.     picker= (CPicker*) pickers->At(current);
  702.     picker->SetColor(color, TRUE);
  703.     newcell->SetColor(color);
  704.     id= cIdNone;
  705.     break;
  706.  
  707.     case cIdCancel:
  708.     color= oldcolor;
  709.     break;
  710.     }
  711.     Dialog::Control(id, part, val);
  712. }
  713.  
  714. HSVColor ColorPicker::PickColor(HSVColor c)
  715. {
  716.     color= c;
  717.     oldcolor= c;
  718.     Dialog::ShowUnderMouse();
  719.     return color;
  720. }
  721.  
  722. HSVColor PickColor(HSVColor c)
  723. {
  724.     if (gPicker == 0)
  725.     gPicker= new ColorPicker("Color Picker");
  726.     return gPicker->PickColor(c);
  727. }
  728.  
  729.